CSS-渲染原理二 渲染层合并 Composite

https://juejin.im/entry/59dc9aedf265da43200232f9

上一篇描述了针对transform、opacity动画化的元素, 浏览器会提升一个合成层来优化渲染
以下几点也会导致浏览器将元素提升到一个新的渲染层.

  1. position: fixed; 直接是一个新的Layer
  2. will-change: transform, opacity; 两者设置其一就会形成 一个新的Layer
  3. translation: transform || opacity || translate3d || filter || backdrop-filter; 需要结合对transform 值的改变才会形成.
  4. video, canvas, iframe; 直接是一个新的Layer;
  5. perspective
  6. 元素A有一个z-index 比自己小的元素B, B是一个合成层(即该元素在复合层上渲染), 则A会提升位合成层(composite隐式合成); 渲染层合并 Composite

http://taobaofed.org/blog/2016/04/25/performance-composite/
http://jartto.wang/2017/08/28/how-to-optimize-marker-of-AMap/
https://www.cnblogs.com/feng9exe/p/10907959.html

  1. DOM树中每个节点都会对应一个LayoutObject, 处于相同坐标空间的LayoutObject会形成一个RenderLayers(渲染层);
  2. RenderLayers保证页面元素以正确的顺序合成, 此时就会出现层合成(composite), 以正确的处理透明元素和重叠元素

ReanderLayers & GraphicsLayers

上图

  • RenderLayers渲染层,是负责对应DOM子树
  • GraphicsLayers图形层, 是负责对应RenderLayers子树
  1. RenedrObjects保持树结构, RenderObject记录如何绘制一个node的内容, RenderObject 通过向绘图上下文(GraphicsContext)发出绘制来绘制nodes
  2. GraphicsLayer有一个GraphicsContext, GraphicsContext负责输出该层的位图, 位图存储在共享内存中, 作为纹理上传到GPU
  3. 最后有GPU将多个位图合成, draw到屏幕上
  4. 某些特殊的渲染层会被认为是合成层(Compositing Layers), 合成层拥有单独的GraphicsLayers.
  5. 其他非合成层的渲染层, 会和其第一个拥有GraphicsLayer父层公用一个.

composite 隐式合成

一个或多个非合成元素如果出现在堆叠顺序上的合成元素之上, 则会提升到合成层, 即被绘制成分离的图像, 将图像交给GPU处理.
例如: 元素A有一个z-index 比自己小的元素B, B是一个合成层(即该元素在复合层上渲染), 则A会提升位合成层(composite隐式合成);

层压缩&层爆炸

浏览器为处理大量合成层的情况, 会对层做Layer Squashing(层压缩)的处理, 但是以下情况无法进行层压缩.

当有大量额外的合成层时, 会出现层爆炸的现象.

  1. 无法进行会打破渲染顺序的压缩
  2. video元素的渲染层无法被压缩同时也无法将别的渲染层压缩到video所在的合成层上
  3. iframe、plugin的渲染层无法被压缩同时也无法将别的渲染层压缩到iframe所在的合成层上
  4. 无法压缩有reflection属性的渲染层
  5. 无法压缩有blend mode属性的渲染层
  6. 当渲染层和合成层有不同的裁减容器时, 该渲染层无法压缩
  7. 相对于合成层滚动的渲染层无法被压缩
  8. 当渲染层和合成层有不同的具有opacity的祖先层(一个设置了opacity < 1, 一个没有设置opacity也算不同), 该渲染层无法压缩
  9. 当渲染层和合成层有不同的具有transform的祖先层时, 该渲染层无法压缩
  10. 当渲染层和合同层有不同的具有filter的祖先层时, 该渲染层无法压缩
  11. 当覆盖的合成层正在运行动画时, 该渲染层无法压缩, 当动画未开始或者运行完毕以后, 该渲染层才可以被压缩